# CourseManager implementation
from typing import Dict, List, Optional, Any
from models.course import Course
from managers.user_manager import UserManager

class CourseManager:
    """
    Course manager - singleton pattern

    Attributes:
        _instance (CourseManager): singleton instance
        courses (Dict[str, Course]): mapping of course_id to Course
    """
    _instance: Optional['CourseManager'] = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.courses: Dict[str, Course] = {}
            self.initialized = True

    @staticmethod
    def get_instance() -> 'CourseManager':
        """Get the singleton instance"""
        return CourseManager()

    def create_course(self, course_info: dict = None, **kwargs) -> Course:
        """Create a course

        Supports two calling styles:
        - Pass a dict: create_course({'course_id': ..., 'name': ..., ...})
        - Use keyword args: create_course(name='...', description='...', ...)

        If course_id is not provided, a unique course_id will be generated in the form course_###.
        """
        # 兼容两种参数风格
        if course_info is None:
            course_info = kwargs or {}

        # 生成唯一的 course_id（如果未提供）
        if 'course_id' not in course_info or not course_info.get('course_id'):
            # 简单生成：course_001, course_002, ...（避免冲突）
            idx = len(self.courses) + 1
            course_id = f"course_{idx:03d}"
            while course_id in self.courses:
                idx += 1
                course_id = f"course_{idx:03d}"
            course_info['course_id'] = course_id

        # 基本验证 - 确保必要字段存在
        required = ['course_id', 'name', 'description', 'teacher_id']
        for field in required:
            if field not in course_info:
                raise ValueError(f"Missing required course field: {field}")

        course = Course(**course_info)
        self.courses[course.course_id] = course

        # 更新教师的授课课程列表
        try:
            user_manager = UserManager.get_instance()
            teacher = user_manager.get_user(course.teacher_id)
            if teacher and hasattr(teacher, 'add_teaching_course'):
                teacher.add_teaching_course(course.course_id)
                user_manager.save_users()  # 保存用户数据更改
                print(f"Updated teacher {teacher.name}'s teaching course list, added course: {course.course_id}")
            else:
                print(f"Warning: Unable to find teacher {course.teacher_id} or teacher object lacks add_teaching_course method")
        except Exception as e:
            print(f"Error updating teacher's teaching courses list: {e}")

        return course

    def get_course(self, course_id: str) -> Optional[Course]:
        """Get a course by ID"""
        return self.courses.get(course_id)

    def list_courses(self) -> List[Course]:
        """List all courses"""
        return list(self.courses.values())

    def get_available_courses(self) -> List[Course]:
        """Get courses that are not full"""
        return [c for c in self.courses.values() if not c.is_full()]
    
    def get_teacher_courses(self, teacher_id: str) -> List[Course]:
        """Get courses taught by the given teacher"""
        return [course for course in self.courses.values() if course.teacher_id == teacher_id]
    
    def get_all_courses(self) -> List[Course]:
        """Return all courses"""
        return list(self.courses.values())

    def get_course_students(self, course_id: str) -> List:
        """Return student user objects for the specified course (empty list if not found)"""
        course = self.get_course(course_id)
        if not course:
            return []

        user_mgr = UserManager.get_instance()
        students = []
        for sid in getattr(course, 'student_ids', []):
            user = user_mgr.get_user(sid)
            if user:
                students.append(user)
        return students

    def drop_student(self, student_id: str, course_id: str) -> bool:
        """Remove a student from a course (return True if removed, False otherwise)"""
        course = self.get_course(course_id)
        if not course:
            return False
        if student_id not in getattr(course, 'student_ids', []):
            return False
        try:
            course.student_ids.remove(student_id)
            course.updated_at = __import__('datetime').datetime.now()
            return True
        except Exception:
            return False

    def update_course(self, course_id: str, update_data: Dict[str, Any]) -> bool:
        """Update course information

        Parameters:
            course_id: ID of the course to update
            update_data: dict of fields to update

        Returns:
            True if update succeeded, False otherwise
        """
        course = self.get_course(course_id)
        if not course:
            return False
        
        try:
            # 定义只读属性列表
            readonly_properties = {'course_id', 'created_at', 'student_ids'}
            
            # 更新课程属性（跳过只读属性）
            for key, value in update_data.items():
                if hasattr(course, key) and key not in readonly_properties:
                    setattr(course, key, value)
            
            # 更新最后修改时间
            course.updated_at = __import__('datetime').datetime.now()
            return True
            
        except Exception as e:
            print(f"Failed to update course: {e}")
            return False
